# Alsophila CMake project file
# Based on Alsophila CMake project file by Prakash Punnoor
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)

IF(NOT DEFINED CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
ENDIF(NOT DEFINED CMAKE_BUILD_TYPE)

SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules")
Project(Alsophila C)

SET(SO_MAJOR_VERSION "0")
SET(SO_MINOR_VERSION "0")
SET(SO_BUILD_VERSION "1")
SET(SO_VERSION "${SO_MAJOR_VERSION}.${SO_MINOR_VERSION}.${SO_BUILD_VERSION}")

IF(${Alsophila_SOURCE_DIR} MATCHES ${Alsophila_BINARY_DIR})
  MESSAGE("Please do an out-of-tree build:")
  MESSAGE("rm -f CMakeCache.txt; mkdir -p default; cd default; cmake ..; make")
  MESSAGE(FATAL_ERROR "in-tree-build detected")
ENDIF(${Alsophila_SOURCE_DIR} MATCHES ${Alsophila_BINARY_DIR})

INCLUDE(${CMAKE_ROOT}/Modules/TestBigEndian.cmake)
INCLUDE(${CMAKE_ROOT}/Modules/CheckCSourceCompiles.cmake)
INCLUDE(${CMAKE_MODULE_PATH}/ConfigHelper.cmake)
INCLUDE(${CMAKE_MODULE_PATH}/HeaderTests.cmake)
INCLUDE(${CMAKE_MODULE_PATH}/FlagsTests.cmake)
INCLUDE(${CMAKE_MODULE_PATH}/DetectCompiler.cmake)

INCLUDE_DIRECTORIES(${Alsophila_BINARY_DIR}/)
INCLUDE_DIRECTORIES(${Alsophila_SOURCE_DIR}/)
INCLUDE_DIRECTORIES(${Alsophila_SOURCE_DIR}/libalsophila)
INCLUDE_DIRECTORIES(${Alsophila_SOURCE_DIR}/alsophila)
INCLUDE_DIRECTORIES(${Alsophila_SOURCE_DIR}/pcm)

SET(LIBALSOPHILA_SRCS libalsophila/a52enc.c
                      libalsophila/a52tab.c
                      libalsophila/bitalloc.c
                      libalsophila/bitalloc_core.c
                      libalsophila/bitio.c
                      libalsophila/crc.c
                      libalsophila/dynrng.c
                      libalsophila/window.c
                      libalsophila/mdct.c
                      libalsophila/exponent.c
                      libalsophila/filter.c
                      libalsophila/util.c
                      libalsophila/convert.c)

SET(ALSOPHILA_SRCS alsophila/alsophila.c alsophila/opts.c)

SET(PCM_SRCS pcm/aiff.c
             pcm/byteio.c
             pcm/caff.c
             pcm/convert.c
             pcm/formats.c
             pcm/pcm.c
             pcm/pcmfile.c
             pcm/pcm_io.c
             pcm/raw.c
             pcm/wav.c)

IF(CMAKE_UNAME)
  EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE CMAKE_SYSTEM_MACHINE)
ELSE(CMAKE_UNAME)
  MESSAGE("Could not detect machine type")
  IF(CMAKE_SYSTEM MATCHES "Windows")
    MESSAGE(STATUS "Assuming i386 machine")
    SET(CMAKE_SYSTEM_MACHINE i386)
  ENDIF(CMAKE_SYSTEM MATCHES "Windows")
ENDIF(CMAKE_UNAME)

DETECT_COMPILER()

CHECK_64BITS()

# GCC compile flags
IF(CMAKE_COMPILER_IS_GNUCC)
  SET(CMAKE_C_FLAGS_RELEASE "-funroll-loops -fomit-frame-pointer ${CMAKE_C_FLAGS_RELEASE}")
  SET(ADD_CFLAGS "-pedantic -Wall -Wpointer-arith -Wredundant-decls -Wformat -Wunused ${ADD_CFLAGS}")

  # gcc 2.9.5 doesn't know following
  CHECK_CFLAGS_APPEND(ADD_EXCLUSIVE_CFLAGS "-std=c99")
  CHECK_CFLAGS_APPEND(ADD_CFLAGS "-Wdisabled-optimization")
  CHECK_CFLAGS_APPEND(ADD_CFLAGS "-Wfloat-equal")
  CHECK_CFLAGS_APPEND(ADD_EXCLUSIVE_CFLAGS "-Wbad-function-cast")

  # gcc 3.0 doesn't know following
  CHECK_CFLAGS_APPEND(ADD_EXCLUSIVE_CFLAGS "-Wdeclaration-after-statement")
  CHECK_CFLAGS_APPEND(ADD_CFLAGS "-Wextra")
  CHECK_CFLAGS_APPEND(ADD_CFLAGS "-Wno-switch")

  # gcc 4.1 doesn't know following
  CHECK_CFLAGS_APPEND(ADD_CFLAGS "-Wstrict-overflow")
ENDIF(CMAKE_COMPILER_IS_GNUCC)

# ICC compile flags
IF(CMAKE_COMPILER_IS_ICC)
  # icc ignores bogus options, so detection makes no sense
  SET(CMAKE_C_FLAGS_RELEASE "-O3 -funroll-loops -fomit-frame-pointer ${CMAKE_C_FLAGS_RELEASE}")
  SET(ADD_CFLAGS "-std=c99 -Wall ${ADD_CFLAGS}")
ENDIF(CMAKE_COMPILER_IS_ICC)

# MSVC compile flags
IF(MSVC)
  # msvc ignores bogus options, so detection makes no sense
  SET(CMAKE_C_FLAGS_RELEASE "/Ot /Oy /Oi /Ox ${CMAKE_C_FLAGS_RELEASE}")
  ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ENDIF(MSVC)

# test for machine endianness
TEST_BIG_ENDIAN(CMAKE_WORDS_BIGENDIAN)
IF(CMAKE_WORDS_BIGENDIAN)
  ADD_DEFINE(WORDS_BIGENDIAN)
ENDIF(CMAKE_WORDS_BIGENDIAN)

# explictly link libm
IF(UNIX)
  SET(LIBM "m")
ENDIF(UNIX)

# add large file support defines
ADD_DEFINITIONS(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)

# check for byteswap.h (gcc extension)
CHECK_INCLUDE_FILE_DEFINE(byteswap.h HAVE_BYTESWAP_H)

# output SVN version to config.h
EXECUTE_PROCESS(COMMAND svn info --xml WORKING_DIRECTORY ${Alsophila_SOURCE_DIR}
OUTPUT_VARIABLE SVN_INFO ERROR_QUIET)
STRING(REGEX MATCH "<entry[^>]+" SVN_VERSION "${SVN_INFO}")
STRING(REGEX MATCH "revision=\"[0123456789]+\"" SVN_VERSION "${SVN_VERSION}")
STRING(REGEX MATCH "[0123456789]+" SVN_VERSION "${SVN_VERSION}")
IF(SVN_VERSION)
  ADD_DEFINE("SVN_VERSION \"${SVN_VERSION}\"")
ENDIF(SVN_VERSION)

GENERATE_CONFIG_H()

SET(CMAKE_C_FLAGS "${ADD_CFLAGS} ${ADD_EXCLUSIVE_CFLAGS} ${CMAKE_C_FLAGS}")

ADD_LIBRARY(alsophila STATIC ${LIBALSOPHILA_SRCS})
SET_TARGET_PROPERTIES(alsophila PROPERTIES LINKER_LANGUAGE C)
TARGET_LINK_LIBRARIES(alsophila ${LIBM} ${ADD_LIBS})

# building a separate static lib for the pcm audio decoder
ADD_LIBRARY(alsophila_pcm STATIC ${PCM_SRCS})

ADD_EXECUTABLE(alsophila_exe ${ALSOPHILA_SRCS})
SET_TARGET_PROPERTIES(alsophila_exe PROPERTIES OUTPUT_NAME alsophila)
SET_TARGET_PROPERTIES(alsophila_exe PROPERTIES LINKER_LANGUAGE C)
IF(WIN32)
  # When linking to static alsophila, dllimport mustn't be used
  SET_TARGET_PROPERTIES(alsophila_exe PROPERTIES COMPILE_FLAGS -DALSOPHILA_BUILD_LIBRARY)
ENDIF(WIN32)
TARGET_LINK_LIBRARIES(alsophila_exe alsophila_pcm alsophila)

INSTALL(TARGETS ${INSTALL_TARGETS} alsophila_exe
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib${LIB_SUFFIX}
        ARCHIVE DESTINATION lib${LIB_SUFFIX})
INSTALL(FILES ${INSTALL_HEADERS} libalsophila/alsophila.h libalsophila/alsophila-types.h DESTINATION include/alsophila)
